<?php
/**
 * @package scottlib.core
 * @author Aaron Collegeman aaroncollegeman.com
 * @version 1.0.0-BETA
 * 
 * Copyright (C)2009 Collegeman.net, LLC.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 */

///////////////////////////////////////////////////////////////////////////////
// This file provides utility functions.
///////////////////////////////////////////////////////////////////////////////

/**
 * @param $arr Array
 * @return true when the array is a numerically indexed array; otherwise, false.
 */
function array_all_keys_numeric($arr) {
	if (!is_array($arr))
		throw new Exception("Parameter must be an array");
	
	$allKeysAreNumeric = true;
	foreach(array_keys($arr) as $key) {
		if (!is_numeric($key)) {
			$allKeysAreNumeric = false;
			break;
		}	
	}

	return $allKeysAreNumeric;
}

/**
 * @return An uncapitalized copy of $name
 */
function struncap($name) {
	return ($name != null) ? strtolower(substr($name, 0, 1)).substr($name, 1) : null;
}

/**
 * @return A capitalized copy of $name
 */
function strcap($name) {
	return ($name != null) ? strtoupper(substr($name, 0, 1)).substr($name, 1) : null;
}

/**
 * Insert a piece of text ($bit) into another piece of text ($phrase)
 * at position $offset, replacing another bit of text that begins at $offset and ends
 * at $offset+$placeholder_length.
 * @param String $phrase The string into which $bit should be inserted
 * @param String $bit The string to be inserted
 * @param int $offset The position in $phrase at which $bit should be inserted
 * @param int $placeholder_length The length of the substring in $phrase, beginning at $offset, to be replaced by $bit
 */
function strpunch($phrase, $bit, $offset, $placeholder_length = 1) {
	return substr($phrase, 0, $offset).$bit.substr($phrase, $offset+$placeholder_length);
}	


/**
 * Used primarily for parameter checking, asserts that the given array contains the given key.
 * @param $key
 * @param $arr
 * @return true when $arr contains $key; otherwise, false.
 */
function assert_array_has_key($key, $arr) {
	if (!array_key_exists($key, $arr))
		throw new Exception("[$key] is required");
}

/**
 * Parse an array of function arguments.  The array may be a key/value pair array
 * (a hash), or an indexed array.  If defined, we first look for $name as a key.
 * If the key is not present in $args, we then move to $pos.  If $pos is not defined
 * in the array and $required = true, an Exception is thrown.  If $required is
 * false, then $default is returned.
 * @param $args
 * @param $name
 * @param $pos
 * @param $required
 * @param $default
 * @return unknown_type
 */
function func_parse_args($args, $name, $pos, $required = false, $default = null) {
	if ($name) {
		if (array_key_exists($name, $args))
			return $args[$name];
	}
	
	if ($pos+1 <= count($args)) {
		return $args[$pos];
	}
		
	if ($required) {
		throw new Exception("Argument [$name] or [$pos] required from ".print_r($args, true));
	}

	return $default;
}

/**
 * @param $string
 * @param $message
 * @throws Exception Bearing $message if $string is null or has a length of 0
 */
function assert_has_length($string, $message = "Value must have length") {
	if ($string === null || !strlen($string))
		throw new Exception($message);
}

/**
 * Generates a GUID from the built-in function uniquid(), the return value of which
 * is hashed using the built-in function md5().
 * @see http://us2.php.net/manual/en/function.uniqid.php
 * @see http://us3.php.net/manual/en/function.md5.php
 * @see http://us3.php.net/manual/en/function.rand.php
 * @return String a non-standard GUID: 16 characters of random alphanumeric goodness.
 */
function sl_guid() {
	return md5(uniqid(rand(), true));
}


function print_pre($obj, $return = false) {
	if ($return)
		return '<pre>'.print_r($obj).'</pre>';
	else
		echo '<pre>'.print_r($obj, true).'</pre>';
}

function is_assignable_from($objOrClassName, $classParent) {
	if (is_string($objOrClassName)) {
		return in_array($classParent, class_parents($objOrClassName));
	}
	else if (is_object($objOrClassName)) {
		return in_array($classParent, class_parents(get_class($objOrClassName)));
	}
}

function assert_is_assignable_from($objOrClassName, $classParent, $message = null) {
	if (!is_assignable_from($objOrClassName, $classParent)) { 
		$className = (is_string($objOrClassName)) ? $objOrClassName : get_class($objOrClassName);
		throw new Exception($message ? $message : "Class $classParent is not in the hierarchy of class $objOrClassName");
	}
}

function assert_is_numeric($value, $message = "Value must be numeric.") {
	if (!is_numeric($value))
		throw new Exception($message . ": " . print_r($value, true));
}
